from django.shortcuts import render
from rest_framework import status
from rest_framework.views import APIView
from rest_framework.response import Response
from .models import User
# Create your views here.
from rest_framework.permissions import IsAuthenticated
from rest_framework.generics import UpdateAPIView
from .serializers import EmailSerializer
class RegisterUsernameCountAPIView(APIView):
    #获取用户名个数
    """
    获取用户名的个数
    GET:  /users/usernames/(?P<username>\w{5,20})/count/
    在光标移动之后，前段需要将用户名发送给后端，我们后端根据提交的用户名进行数据库的查询
    如果数据存在 表示已经注册
    如果数据不存在 表示没有注册
     """
    def get(self,request,username):

        count = User.objects.filter(username=username).count()
       #我们需要返回   1：表示已经注册     0：表示没注册
        context = {
            'count':count,
            'username':username
        }
        return Response(context)



class RegisterPhoneCountAPIView(APIView):
    #查询手机号的个数
    #  GET： /Users/phone/(?p<mobile>1[3456789]\d{9}/count)
    def get(self,request,mobile):
        #通过模型查询手机号个数
        count = User.objects.filter(mobile=mobile).count()
        #组织数据
        context = {
            'count':count,
            'phone':mobile
        }
        return Response(context)


# APIView
# GenericAPIView  --- 是否用到序列化器
# CreateAPIView

from .serializers import RegisterUserSerializer
from rest_framework.mixins import CreateModelMixin
class RegisterUserView(APIView):
# """
# POST  /users/
# 前端把数据提交给后端，后端把数据进行效验，然后数据入库
# 1.前段必须把用户名，密码，手机号发送过来，确认密码，短信，是否同意我们后端为安全考虑，也让前段发送过来
# 2.后端接受这些数据，我们需要对数据进行效验
# 3.效验没有问题就入库
# """
    def post(self,request):
        serializer = RegisterUserSerializer(data=request.data)
        #进行效验
        serializer.is_valid()
        #保存数据
        serializer.save()

        #序列化操作，将user信息 转换为json
        return Response(serializer.data)

#用户注册完成后，就认为是登陆了
from rest_framework.permissions import IsAuthenticated
from rest_framework.generics import RetrieveAPIView
from rest_framework.generics import GenericAPIView
from rest_framework.mixins import CreateModelMixin
from .serializers import UserInfoSerializer
# # 第二级视图 GenericAPIView
# class RegisterUserView(CreateModelMixin,GenericAPIView):
#     """
#     POST        /users/
#     前端把数据提交给后端,我们后端进行数据的校验,然后数据入库
#
#
#     1. 前端必须把用户名,密码和手机号发送过来, 确认密码,短信,是否同意我们后端为了安全考虑,也让前端
#         发送过来
#     2.后端接受这些数据,我们需要对数据进行校验
#     3. 校验没有问题就入库
#
#     """
#
#     serializer_class =  RegisterUserSerializer
#
#     def post(self, request):
#
#
#         return self.create(request)


# from rest_framework.generics import CreateAPIView
# # 视图的第三级 (抽取)
# class RegisterUserView(CreateAPIView):
#     serializer_class = RegisterUserSerializer



# from users.serialziers import RegisterUserSerializer

class UserDetailView(RetrieveAPIView):
    #获取登陆用户的信息
    #GET/users/
    #既然是登陆用户，我们就要用权限管理
    #在类视图对象中也保存了请求对象request
    #request对象user属性是通过认证检验之后的请求用户对象

    #     #添加 权限
    #     permission_classes = [IsAuthenticated]
    #     def get(self,request):
    #         # 如何获取user信息? request.user
    #         user = request.user
    #         # user 默认是一个匿名用户
    #         #  如果用户登录了, user就是登录的用户信息
    #         #将模型通过序列化器转换
    #         serializer = UserInfoSerializer(instance=user)
    #         return Response(serializer.data)

    permission_classes = [IsAuthenticated]
    serializer_class = UserInfoSerializer

    # queryset = User.objects.all()
    # get_object 相当于 我们在基础中将的 根据id获取指定信息
    def get_object(self):
        return self.request.user

class EmailView(UpdateAPIView):
    #PUT/users/emails/
    """
        1. 我们要求前端 把用户的邮箱 发送过来
        2. 我们后台,需要能够将这个信息 保存起来,保存指定的记录中(更新数据)
            这个接口必须传递用户信息, 这个接口只能是登录用户才可以访问
        3. 邮箱信息保存了之后,我们要发送激活邮件
            如何发邮件
            激活邮件的内容该如何生成
        """
    #必须是登陆用户
    permission_classes = [IsAuthenticated]
    serializer_class = EmailSerializer

    # 父类的 get_object 是通过 pk来获取数据的,但是它不能满足我们的需求
    # 我们制定 get_object 就是获取指定用户信息,所以重写,直接将 request.user返回
    def get_object(self):
        # User.objects.get(pk=xxx) 不能这么写了,因为没有pk
        return self.request.user

from rest_framework.generics import ListAPIView
from .serializers import UserListSerializer

class UserListView(GenericAPIView):
    # serializer_class = UserListSerializer
    def get_serializer_class(self):
        return UserListSerializer
    # queryset = User.objects.all()

    #或者重写
    def get_queryset(self):
        return User.objects.all()
    def get(self,request):
        #1.查询到所有数据
        books = self.get_queryset()
        #2.创建序列化器，用序列化器实现将模型转换为字典
        #Userlistserializer---serializer(books,many=true)
        serializer = self.get_serializer(books,many=True)
        #3.返回数据
        return Response(serializer.data)

class EmailActiveView(APIView):
    """
        GET users/emails/active?token=xxxxx
        # 1.用户点击url的时候会发送一个get请求,get请求会携带token信息
        # 2.我们对token信息进行解析
        # 3. 改变用户的状态
        """
    def get(self,request):
        #1.用户点击url时候会发送一个get请求，get请求会带token信息
        token = request.query_params.get('token')
        if token is None:
            return Response(status=status.HTTP_400_BAD_REQUEST)
        #2.我们对token信息进行解析
        # user = User().generic_user_info(token)  这么写没有意义
        user = User.generic_user_info(token)
        if user is None:
            return Response(status=status.HTTP_400_BAD_REQUEST)
        #3.改变用户状态
        user.email_active = True
        user.save()

        return Response({'message':'ok'})
    
    
#历史浏览记录
from .serializers import UserHistorySerializer,SKUSerialzier
from django_redis import get_redis_connection
from goods.models import SKU
#这个视图可以优化
class UserHistoryView(GenericAPIView):
    """
        分析:
        1. 未登录用户的历史记录保存在cookie中, 登录用户的历史记录保存在服务器(实现这个功能)
        2. 保存在服务器端(Redis,Mysql),选择是 Redis
        3. Redis保存什么数据(sku_id),什么数据格式(List)

        POST    /users/histories/       {'sku_id':xxx}  新增历史记录

        思路:
        1. 当登录用户访问商品详情页面的时候,需要让前段 发送一个 请求,请求中要求包含商品id的信息
        2. 后端接受这个请求, 这个请求包含 sku_id, 我们需要对商品id进行校验
        3. 将商品的id保存到redis中

        GET    /users/histories/     获取历史记录
        1. 必须是返回登录用户的信息
        # 2. 获取redis中的数据 (sku_id,sku_id)
        # 3. 我们需要根据id来获取商品的详细信息
        # 4. 商品的详细信息是模型,需要将模型转换为字典

        """
    #权限
    permission_classes = [IsAuthenticated]
    serializer_class = UserHistorySerializer
    def post(self,request):
        serializer = self.get_serializer(data=request.data)
        #检验数据
        serializer.is_valid()
        #数据保存
        serializer.save()
        return Response(serializer.data)

    def get(self,request):
        redis_conn = get_redis_connection('history')
        redis_ids = redis_conn.lrange('history_%s'%request.user.id,0,5)
        # [id,id,id]
        # 3. 我们需要根据id来获取商品的详细信息
        # skus = SKU.objects.filter(id__in=redis_ids)
        # 如果我们按照 SKU.objects.filter(id__in=redis_ids) 语句查询商品的详细信息
        # 确实可以查询出来,但是商品的顺序被改变了,
        # 我们需要保留原来的顺序
        skus = []
        for sku_id in redis_ids:
            sku = SKU.objects.get(pk=sku_id)
            skus.append(sku)
        # [SKU,SKU,SKU]
        # 4. 商品的详细信息是模型,需要将模型转换为字典
        serializer = SKUSerialzier(instance=skus,many=True)
        return Response(serializer.data)